﻿using System;
using System.Collections.Generic;
using System.Text;
using RabbitMQDemo.Common;

namespace RabbitMQDemo.Producer
{
    public class DeadLetter
    {
        private const string ExchangeName = "dead_letter_exchange";

        private const string QueueName = "dead_letter_queue";

        private const string RoutingKey = "dead_letter_routing";

        private const string DLX_ExchangeName = "dead_letter_exchange_dlx";

        private const string DLX_QueueName = "dead_letter_queue_dlx";

        private const string DLX_RoutingKey = "dead_letter_routing_dlx";

        public static void Send(string[] args)
        {
            using var connection = MQClient.GetConnection();
            using var channel = connection.CreateModel();

            // 声明死信交换机、死信队列
            channel.ExchangeDeclare(exchange: DLX_ExchangeName, type: "direct", durable: false, autoDelete: false, arguments: null);
            channel.QueueDeclare(queue: DLX_QueueName, durable: false, exclusive: false, autoDelete: false, arguments: null);
            channel.QueueBind(queue: DLX_QueueName, exchange: DLX_ExchangeName, routingKey: DLX_RoutingKey, arguments: null);

            // 声明交换机、队列
            channel.ExchangeDeclare(exchange: ExchangeName, type: "direct", durable: false, autoDelete: false, arguments: null);
            channel.QueueDeclare(queue: QueueName, durable: false, exclusive: false, autoDelete: false, arguments: new Dictionary<string, object> {
                { "x-dead-letter-exchange", DLX_ExchangeName }, // 设置当前队列的死信交换机DLX
                { "x-dead-letter-routing-key", DLX_RoutingKey }, // 设置死信路由key，DLX会根据该值去找到死信消息存放的队列
                // { "x-expires", 10000 }, // 队列过期时间
                { "x-message-ttl", 6000 } // 消息过期时间
            });
            channel.QueueBind(queue: QueueName, exchange: ExchangeName, routingKey: RoutingKey, arguments: null);

            var index = 0;
            while (index < 10)
            {
                // 设置消息过期时间
                var ttl = new Random().Next(3000, 6000);

                var properties = channel.CreateBasicProperties();
                // properties.Expiration = ttl.ToString();

                // 发送消息
                channel.BasicPublish(exchange: ExchangeName, routingKey: RoutingKey, mandatory: false, basicProperties: properties, body: GetMessage(index));

                // Thread.Sleep(1000);
                Console.WriteLine($"[{index}]Send dlx message. ttl={ttl}");
                index++;
            }
        }

        private static byte[] GetMessage(int? i = null) => Encoding.UTF8.GetBytes($"[DeadLetter]{(i.HasValue ? $"[{i}]" : string.Empty)} message");
    }
}
